Spring Security Complete Notes
Table of Contentsโ
- Introduction to Spring Security
- Core Architecture
- Authentication vs Authorization
- Password Encoding with BCrypt
- JWT (JSON Web Tokens)
- Refresh Tokens
- HttpOnly Cookies
- Role-Based Access Control (RBAC)
- Security Configuration
- Custom Authentication Provider
- Method-Level Security
- CSRF Protection
- CORS Configuration
- Session Management
- OAuth2 Integration
- Security Best Practices
Introduction to Spring Securityโ
Spring Security is a powerful and highly customizable authentication and access-control framework for Spring applications. It provides comprehensive security services for Java EE-based enterprise software applications.
Key Features:โ
- Authentication: Verifying the identity of users
- Authorization: Controlling access to resources
- Protection against attacks: CSRF, session fixation, clickjacking, etc.
- Servlet API integration: Works seamlessly with Spring Boot
- Password encoding: Built-in support for various encoding algorithms
- Remember-me authentication: Persistent login functionality
Core Architectureโ
Security Filter Chainโ
Spring Security uses a chain of filters to process security-related tasks:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.permitAll()
)
.logout(logout -> logout.permitAll());
return http.build();
}
}
Key Components:โ
- SecurityContext: Holds security information about current user
- Authentication: Represents user credentials and authorities
- AuthenticationManager: Processes authentication requests
- UserDetailsService: Loads user-specific data
- PasswordEncoder: Encodes passwords securely
Authentication vs Authorizationโ
Authenticationโ
Process of verifying who the user is.
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));
return org.springframework.security.core.userdetails.User.builder()
.username(user.getUsername())
.password(user.getPassword())
.authorities(user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName()))
.collect(Collectors.toList()))
.build();
}
}
Authorizationโ
Process of determining what the authenticated user is allowed to do.
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin/users")
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@PreAuthorize("hasRole('USER') and #userId == authentication.principal.id")
@GetMapping("/user/{userId}/profile")
public UserProfile getUserProfile(@PathVariable Long userId) {
return userService.getUserProfile(userId);
}
Password Encoding with BCryptโ
BCrypt is a password hashing function designed to be slow and computationally expensive, making it resistant to brute-force attacks.
Theory:โ
- Salt: Random data added to password before hashing
- Cost Factor: Controls how slow the algorithm runs
- One-way function: Cannot be reversed to get original password
Implementation:โ
@Configuration
public class PasswordConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12); // Strength of 12
}
}
@Service
public class UserService {
@Autowired
private PasswordEncoder passwordEncoder;
public void createUser(String username, String rawPassword) {
String encodedPassword = passwordEncoder.encode(rawPassword);
User user = new User(username, encodedPassword);
userRepository.save(user);
}
public boolean verifyPassword(String rawPassword, String encodedPassword) {
return passwordEncoder.matches(rawPassword, encodedPassword);
}
}
BCrypt Strengths:โ
- 10: 2^10 = 1,024 rounds (fast, for testing)
- 12: 2^12 = 4,096 rounds (recommended for production)
- 15: 2^15 = 32,768 rounds (very secure, slower)
JWT (JSON Web Tokens)โ
JWT is a compact, URL-safe means of representing claims between two parties.
Structure:โ
Header.Payload.Signature
Header:โ
{
"alg": "HS256",
"typ": "JWT"
}